package com.qfmy.web.controller;

import com.qfmy.baseCode.bean.TableInfo;
import com.qfmy.baseCode.builder.BuilderTable;
import com.qfmy.baseCode.consts.CommonPropertiesConst;
import com.qfmy.baseCode.consts.PathAndPackageConst;
import com.qfmy.baseCode.utils.CommentUtils;
import com.qfmy.baseCode.utils.CommonPropertiesUtils;
import com.qfmy.baseCode.utils.PropertiesUtils;
import com.qfmy.web.consts.Result;
import com.qfmy.web.entity.MysqlDao.MysqlConfigDao;
import com.qfmy.web.entity.Operate.AutoCode;
import com.qfmy.web.entity.Operate.OperateBean;
import com.qfmy.web.entity.Operate.OperateLogin;
import com.qfmy.web.entity.Operate.OperateTableAndFiled;

import com.qfmy.web.entity.page.PageBean;
import com.qfmy.web.exception.BaseException;
import com.qfmy.web.service.OperateService;

import jakarta.annotation.Resource;
import lombok.SneakyThrows;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.jdbc.ScriptRunner;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.*;
import java.nio.charset.Charset;
import java.sql.Connection;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;

/**
 * @author: 廖志伟
 * @date: 2024-11-28
 * @description: 操作控制器
 */
@SuppressWarnings("all")
@RestController
@RequestMapping("/operate")
public class OperateController {
    @Autowired
    private OperateService operateService;
    //redis对象模板
    @Resource
    private RedisTemplate<String, Object> redisTemplate;
    //定义一个静态的表信息集合
    public  List<com.qfmy.baseCode.bean.TableInfo> tableInfos = new ArrayList<>();
    //操作登入的类
    private OperateLogin operateLogin;
    //操作类
    private OperateBean operateBean;
    //操作表和字段的类
    private OperateTableAndFiled operateTableAndFiled;
    @Autowired
    private FileUploadController fileUploadController;


    /**
     * 生成登录接口
     * @param operateLogin
     * @return
     */
    @RequestMapping("/login")
    public Result OperateLogin(@RequestBody OperateLogin operateLogin){
        this.operateLogin = operateLogin;
        return Result.success(200,"操作成功");
    }

    /**
     * 生成操作类接口
     * @param operateBean
     * @return
     */
    @PostMapping("operateClass")
    public Result operateClass(@RequestBody OperateBean operateBean){
        this.operateBean = operateBean;
        return Result.success(200,"操作成功");
    }

    /**
     * 生成操作表和字段接口
     * @param operateTableAndFiled
     * @return
     */
    @PostMapping("operateTableAndFiled")
    public Result operateTableAndFiled(@RequestBody OperateTableAndFiled operateTableAndFiled){
        this.operateTableAndFiled = operateTableAndFiled;
        return Result.success(200,"操作成功");
    }

    /**
     * 生成操作代码接口
     * @return
     */
   @GetMapping("operateCode")
   public Result operateCode(){
       //定义主要项目的名称
       PathAndPackageConst.PATH_BASE = operateBean.getParentName() + "/" + operateBean.getBaseProjectName()  + "/"+ PropertiesUtils.getProperty("path.base");
       //定义模块的名称
       CommonPropertiesConst.BASE_PATH =operateBean.getParentName() + "/" + operateBean.getCommonProjectName()  + "/" + CommonPropertiesUtils.getProperty("path.common");
       //定义一个xml生成路径
       PathAndPackageConst.PATH_XML=  operateBean.getParentName() + "/" + operateBean.getBaseProjectName()  + "/src/main/resources/mapper";


       //生成代码
       AutoCode autoCode = new AutoCode(operateLogin,operateBean,operateTableAndFiled);
       //注释的作者名称
       CommentUtils.AUTHOR_NAME = operateTableAndFiled.getAuthor();
       //开始创建表
       BuilderTable builderTable = new BuilderTable();
       builderTable.setOperateService(operateService);
       List<TableInfo> ts;
       //获取表信息
       Optional<List<TableInfo>> tables = Optional.ofNullable(builderTable.getTables());
       if(this.tableInfos.size() != 0 && tables.isPresent())
       {
            ts = tables.orElseThrow();
            ts.addAll(this.tableInfos);
       }else
       {
           ts = tables.orElseThrow();
            autoCode.execute(ts);
       }
      return Result.success(200,"代码生成成功");
   }

    /**
     * 获取所有表的信息
     * @return
     */
    @GetMapping("/getAllTable")
    public Result<List<com.qfmy.web.entity.MysqlDao.TableInfo>> getAllTable() {
        // 定义一个表信息集合
        List<com.qfmy.web.entity.MysqlDao.TableInfo> tableInfo = null;
        tableInfo = operateService.getAllTable();
        // 返回结果
        return Result.success(200, tableInfo);
    }

    /**
     * 根据分页查询获取所有的表信息
     *
     * @param pageNum
     * @param pageSize
     * @param tableName
     * @param createDate
     * @return
     */
    @GetMapping("/getAllTablePage")
    public Result<PageBean<com.qfmy.web.entity.MysqlDao.TableInfo>> list(Integer pageNum, Integer pageSize
            , @RequestParam(required = false) String tableName, @RequestParam(required = false) String createDate) {
        // 调用mysqlService的list方法获取所有表的信息
        PageBean<com.qfmy.web.entity.MysqlDao.TableInfo> pageBean = operateService.list(pageNum, pageSize, tableName, createDate);
        // 返回结果
        return Result.success(200, pageBean);
    }

    @SneakyThrows
    @Transactional(rollbackFor = Exception.class)
    @GetMapping("/addTable")
    public Result addTable(String sqlContent) {
        String[] split = sqlContent.split(" ");
        //获取表名
        String tableName = split[2];
        //获取数据库的连接
        Connection connection = MysqlConfigDao.getConnection();
        //创建一个脚本执行器
        ScriptRunner scriptRunner = new ScriptRunner(connection);
        //设置脚本执行器的编码
        Resources.setCharset(Charset.forName("UTF-8"));
        scriptRunner.setSendFullScript(true);
        //执行脚本
        scriptRunner.runScript(new StringReader(sqlContent));
        BuilderTable builderTable = new BuilderTable();
        builderTable.setOperateService(operateService);
        //进行创建表
        List<com.qfmy.baseCode.bean.TableInfo> tables = builderTable.getTables();
        this.tableInfos.add(tables.get(0));
        //返回结果
        return Result.success(200, "成功添加");
    }

    /**
     * 上传sql文件
     *
     * @param file
     * @return
     */
    @SneakyThrows
    @Transactional(rollbackFor = Exception.class)
    @PostMapping("/sqlFile")
    public Result sqlFile(@RequestParam("file") MultipartFile file) {
        //获取文件的名称
        String fileName = file.getOriginalFilename();
        //对文件类型进行判断
        if (!fileName.endsWith(".sql")) {
            throw new BaseException(500, "该文件不是sql文件,请重新上传");
        }
        //获取数据库的连接
        Connection connection = MysqlConfigDao.getConnection();
        System.out.println("连接：" + connection);
        //创建一个脚本执行器
        ScriptRunner scriptRunner = new ScriptRunner(connection);
        //设置脚本执行器的编码
        Resources.setCharset(Charset.forName("UTF-8"));
        scriptRunner.setSendFullScript(true);
        //执行脚本
        scriptRunner.runScript(new InputStreamReader(file.getInputStream()));
        BuilderTable builderTable = new BuilderTable();
        builderTable.setOperateService(operateService);
        //创建表
        List<com.qfmy.baseCode.bean.TableInfo> tables = builderTable.getTables();
        //添加表信息
        this.tableInfos.addAll(tables);
        //返回结果
        return Result.success(200, "成功上传");
    }

    @DeleteMapping("/deleteTableByTableName")
    public Result deleteTableByTableName(@RequestParam("tableName") String tableName) {
        //删除表
        operateService.deleteByTableName(tableName);
        //返回结果
        return Result.success(200, "成功删除");
    }


}
